package com.ld.admin.controller.system.systeminfo;

import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.text.DecimalFormat;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;

import javax.servlet.ServletException;

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ld.admin.controller.AdminBasicController;
import com.ld.shieldsb.common.core.util.os.OSUtil;
import com.ld.shieldsb.common.web.model.SysUser;
import com.ld.shieldsb.common.web.util.Web;
import com.sun.management.OperatingSystemMXBean;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@Api(tags = "java虚拟机管理")
@ConditionalOnProperty(prefix = "modules.sc.system", name = "jvm.enable", havingValue = "true", matchIfMissing = true)
@Controller
@RequestMapping("${shieldsb.adminPath}/system/jvm")
public class JVMCacheController extends AdminBasicController<SysUser> {
    @SuppressWarnings("restriction")
    @ApiOperation(value = "虚拟内存管理", notes = "")
    @RequestMapping(path = "", method = RequestMethod.GET)
    public String index() {
        Runtime runtime = Runtime.getRuntime();
        DecimalFormat mbFormat = new DecimalFormat("#0.00");
        DecimalFormat percentFormat = new DecimalFormat("#0.0");
        int numBlocks = 50;
        int byteToMb = 1024 * 1024;
        double freeMemory = (double) runtime.freeMemory() / byteToMb;
        double totalMemory = (double) runtime.totalMemory() / byteToMb;
        double maxMemory = (double) runtime.maxMemory() / byteToMb;
        double usedMemory = totalMemory - freeMemory;
        double percentFree = freeMemory / totalMemory * 100.0;
        int free = 100 - (int) Math.round(percentFree);
        request.setAttribute("usedMemory", mbFormat.format(usedMemory)); // 已用内存
        request.setAttribute("totalMemory", mbFormat.format(totalMemory)); // 已经分配的内存总量
        request.setAttribute("maxMemory", mbFormat.format(maxMemory)); // 分配的最大内存
        request.setAttribute("availableProcessors", runtime.availableProcessors()); // 处理器数
        request.setAttribute("num_blocks", numBlocks); // 分的块数
        request.setAttribute("percentFree", percentFormat.format(percentFree)); // 空闲率
        request.setAttribute("free", free); // 使用的百分值

        ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
        while (threadGroup.getParent() != null) {
            threadGroup = threadGroup.getParent();
        }
        int totalThread = threadGroup.activeCount();

        // 操作系统级内存情况查询
        OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
        String os = OSUtil.getOSName();
        long physicalTotal = osmxb.getTotalPhysicalMemorySize() / byteToMb;
        long physicalFree = osmxb.getFreePhysicalMemorySize() / byteToMb; // 注意free是对系统而言的空闲空间并非总大小-实际使用大小（可能还需要去除cache）
        long physicalUse = physicalTotal - physicalFree;
        long swapTotal = osmxb.getTotalSwapSpaceSize() / byteToMb;
        long swapFree = osmxb.getFreeSwapSpaceSize() / byteToMb;
        long swapUse = swapTotal - swapFree;
        request.setAttribute("os", os); // 操作系统的版本
        request.setAttribute("physicalFree", physicalFree); // 操作系统物理内存已用的空间为
        request.setAttribute("physicalUse", physicalUse); // 操作系统物理内存的空闲空间
        request.setAttribute("physicalTotal", physicalTotal); // 操作系统总物理内存
        request.setAttribute("swapFree", swapFree); // 交换空间的空闲空间
        request.setAttribute("swapUse", swapUse); // 交换空间的使用大小
        request.setAttribute("swapTotal", swapTotal); // 交换空间的总大小

        request.setAttribute("runtimeVersion", System.getProperty("java.specification.vendor") + " "
                + System.getProperty("java.runtime.name") + "(" + System.getProperty("java.runtime.version") + ")"); // 操作系统总物理内存

        request.setAttribute("totalThread", totalThread); // 线程数
        return "a/system/jvmcache/show";
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @ApiOperation(value = "java环境变量", notes = "")
    @RequestMapping(path = "properties", method = RequestMethod.GET)
    public String properties() {
        Properties properties = System.getProperties();
        Map<String, String> map = new LinkedHashMap<String, String>((Map) properties);
        Map<String, String> result = new LinkedHashMap<>();

        map.entrySet().stream().sorted(Map.Entry.<String, String> comparingByKey()
//                .reversed() //倒序
        ).forEachOrdered(e -> result.put(e.getKey() + "", e.getValue() + ""));

        request.setAttribute("properties", result);
        return "a/system/jvmcache/properties";
    }

    @ApiOperation(value = "垃圾回收", notes = "")
    @RequestMapping(path = "/gc", method = RequestMethod.POST)
    // 返回json格式
    @ResponseBody
    public Object gc() throws ServletException, IOException {
        Runtime runtime = Runtime.getRuntime();
        runtime.gc();
        return Web.Response.success("垃圾收集完成！");
    }

}
